package pe.com.astech.web.service;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.servlet.ServletContext;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.aspectj.apache.bcel.classfile.Constant;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;

import pe.com.astech.web.bean.MaquinariaBean;
import pe.com.astech.web.bean.ModuloBean;
import pe.com.astech.web.bean.SubModuloBean;
import pe.com.astech.web.bean.TipoModuloBean;
import pe.com.astech.web.dao.MaquinariaDao;
import pe.com.astech.web.util.Constantes;

@Service
public class MaquinariaServiceImpl implements MaquinariaService {

	@Autowired
	public MaquinariaDao maquinariaDao;
	@Autowired
	ServletContext context;

	private static final Log log = LogFactory.getLog(MaquinariaServiceImpl.class);
	
	@Override
	public List<MaquinariaBean> obtenerMaquinaria(
			String mensajeTrazabilidad, String id_orden_pedido) {
		// TODO Auto-generated method stub
		return maquinariaDao.obtenerMaquinaria(mensajeTrazabilidad, id_orden_pedido);
	}

	@Override
	public List<MaquinariaBean> obtenerMaquinaria(
			String mensajeTrazabilidad) {
		// TODO Auto-generated method stub
		return maquinariaDao.obtenerMaquinaria(mensajeTrazabilidad);
	}

	@Override
	public List<MaquinariaBean> buscarMaquinarias(String mensajeTrazabilidad,
			MaquinariaBean maquinariaBean) {
		// TODO Auto-generated method stub
		return maquinariaDao. buscarMaquinarias(mensajeTrazabilidad,
				maquinariaBean);
	}

	@Override
	public String guardarMaquinaria(String mensajeTrazabilidad,
			MaquinariaBean maquinariaBean) {
		
		String path = "";
		String estado = Constantes.OK;
		String nombreAsignado = maquinariaBean.getNombre_new()+"_"+maquinariaBean.getModelo_new();
		
		if (!maquinariaBean.getArchivo().isEmpty()) {
			log.info(mensajeTrazabilidad + " size: " + maquinariaBean.getArchivo().getSize());
			log.info(mensajeTrazabilidad + " ContentType: " + maquinariaBean.getArchivo().getContentType());
			log.info(mensajeTrazabilidad + " name: " + maquinariaBean.getArchivo().getName());
			log.info(mensajeTrazabilidad + " originalFileName: " + maquinariaBean.getArchivo().getOriginalFilename());
			int posicion = maquinariaBean.getArchivo().getOriginalFilename().indexOf(".");
			log.info(mensajeTrazabilidad + " posicion: " + posicion);
			String extension = maquinariaBean.getArchivo().getOriginalFilename().substring(posicion);
			log.info(mensajeTrazabilidad + " extension: " + extension);
			String nombre = maquinariaBean.getArchivo().getOriginalFilename().substring(Constantes.intCERO,posicion);
			log.info(mensajeTrazabilidad + " nombre: " + nombre);
			FileOutputStream fos = null;
			try {
				path = context.getRealPath("/");
				path = path+Constantes.NOMBRE_MAQUINARIA_PATH;
				log.info(mensajeTrazabilidad + " " +"ruta: " + path);
				
				
				maquinariaBean.setRuta_documento(path+"/" + nombre+"_"+nombreAsignado+extension);
				maquinariaDao.guardarMaquinaria(mensajeTrazabilidad,maquinariaBean);
				
				
				File carpeta = new File(path);
				log.info(mensajeTrazabilidad + " " +"carpeta: " + carpeta);
				if(null!=carpeta.listFiles() && carpeta.listFiles().length > 0){
					for(int i=0;i<carpeta.listFiles().length;i++){
						log.info(mensajeTrazabilidad + " " +"archivos: " + carpeta.listFiles()[i].getName());
						if(carpeta.listFiles()[i].getName().equals(nombre+"_"+nombreAsignado+extension)){
							log.info(mensajeTrazabilidad + carpeta.listFiles()[i].getName());
							log.info(mensajeTrazabilidad + " eliminacion: " + carpeta.listFiles()[i].delete());
						}
					}
				}
				log.info(mensajeTrazabilidad + " " +"ruta completa: " + path+"/" + nombre+"_"+nombreAsignado+extension);
				
				fos = new FileOutputStream(path+"/" + nombre+"_"+nombreAsignado+extension);
				fos.write(maquinariaBean.getArchivo().getBytes());
				
				log.info(mensajeTrazabilidad + " " +"Archivo subido correctamente");
				
				
				
			} catch (Exception e) {
				log.error(mensajeTrazabilidad + " Exception " +e.getMessage());
				estado = Constantes.NOOK;
			} finally {
				try {
					if (fos != null)
						fos.close();
				} catch (IOException e) {
					log.error(mensajeTrazabilidad + " IOException " +e.getMessage());
					estado = Constantes.NOOK;
				}
			}
		} else {
			log.error(mensajeTrazabilidad + " Error al subir archivo");
			estado = Constantes.NOOK;
		}
		
		return estado;
	}
	
	@Override
	public ResponseEntity<byte[]> descargarMaquinaria(
			String mensajeTrazabilidad, String id_maquinaria,List<MaquinariaBean> list) {
				
		ResponseEntity<byte[]> response = null;
		HttpHeaders headers = new HttpHeaders();
		MaquinariaBean maquinariaBean = new MaquinariaBean();
		for(int i=0;i<list.size();i++){
			String id = list.get(i).getId_maquinaria();
			if(id.equals(id_maquinaria)){
				maquinariaBean = list.get(i);
				break;
			}
		}
		
		log.info(mensajeTrazabilidad+" "+maquinariaBean.toString());
		
		File file = new File(maquinariaBean.getRuta_documento());
		
			byte[] contents = new byte[(int) file.length()];
		
			FileInputStream fis = null;
			try {
				fis = new FileInputStream(file);
				fis.read(contents, 0, contents.length);
	
				log.info("Se descargo el archivo correctamente");
			} catch (FileNotFoundException e) {
				log.error(e.getMessage());
			} catch (IOException e) {
				log.error(e.getMessage());
			} finally {
				try {
					if (fis != null)
						fis.close();
				} catch (IOException e) {
					log.error(e.getMessage());
				}
			}
			
			String filename = file.getName();
			headers.setContentDispositionFormData(filename, filename);
			
			if(file.getName().endsWith(".xls"))
				headers.setContentType(MediaType.parseMediaType("application/vnd.ms-excel"));
			else if (file.getName().endsWith(".xlsx"))
				headers.setContentType(MediaType.parseMediaType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"));
			else if (file.getName().endsWith(".pdf"))
				headers.setContentType(MediaType.parseMediaType("application/pdf"));
		
			response = new ResponseEntity<byte[]>(contents, headers, HttpStatus.OK);
		
		return response;
	}
	
	
	@Override
	public String actualizarMaquinaria(String mensajeTrazabilidad,
			MaquinariaBean maquinariaBean,List<MaquinariaBean> listaMaquinaria) {
		
		String respuesta = "";
		maquinariaDao.actualizarMaquinaria(mensajeTrazabilidad,maquinariaBean);
		
		for(int i=0;i<listaMaquinaria.size();i++){
			String id = listaMaquinaria.get(i).getId_maquinaria();
			if(id.equals(maquinariaBean.getId_maquinaria())){
				maquinariaBean.setRuta_documento(listaMaquinaria.get(i).getRuta_documento());
				break;
			}
		}
		log.info(mensajeTrazabilidad+" "+maquinariaBean.toString());
		
		if(maquinariaBean.getEstado_new().equals(Constantes.ESTADO_MAQUINARIA_APROBADO)){
			respuesta = leerExcel(mensajeTrazabilidad,maquinariaBean);
		}
	
		return respuesta;
	}

	
	public String leerExcel(String mensajeTrazabilidad, MaquinariaBean maquinariaBean){
		String respuesta = "";
		String path = maquinariaBean.getRuta_documento();
        try {
        	mensajeTrazabilidad = mensajeTrazabilidad + " leerExcel ";
        	List<SubModuloBean>listSubModulo = new ArrayList<SubModuloBean>();
        	List<ModuloBean>listModulo = new ArrayList<ModuloBean>();
        	List<ModuloBean>listModuloEval = new ArrayList<ModuloBean>();
            //Get the workbook instance for XLS file
            Workbook workbook = WorkbookFactory.create(new FileInputStream(path));
            
            //Get first sheet from the workbook
            Sheet sheet = workbook.getSheetAt(0);
            
            //Iterate through each rows from first sheet
            Iterator<Row> rowIterator = sheet.iterator();
            while(rowIterator.hasNext()) {
                Row row = rowIterator.next();
                
                //For each row, iterate through each columns
                Iterator<Cell> cellIterator = row.cellIterator();
                int count = 0;
                SubModuloBean bean = new SubModuloBean();
                String codigo = "";
                String modulo = "";
                String submodulo = "";
                String accesorios = "";
                String verificar = "";
                String componente = "";
                String especificacion = "";
                String tipo = "";
                
                while(cellIterator.hasNext()) {
                	count++;
                    Cell cell = cellIterator.next();
                    
                    switch(cell.getCellType()) {
                        case Cell.CELL_TYPE_BOOLEAN:
                        	log.info(mensajeTrazabilidad + " " + cell.getBooleanCellValue() + "\t\t");
                            break;
                        case Cell.CELL_TYPE_NUMERIC:
                        	log.info(mensajeTrazabilidad + " " + cell.getNumericCellValue() + "\t\t");
                            break;
                        case Cell.CELL_TYPE_STRING:
                        	if(count==Constantes.intUNO){
                        		codigo = cell.getStringCellValue();
                        		log.info(mensajeTrazabilidad + " codigo " + cell.getStringCellValue());
                        	}
                        	else if(count==Constantes.intDOS){
                        		modulo = cell.getStringCellValue();
                        		log.info(mensajeTrazabilidad + " modulo " + cell.getStringCellValue());
                        	}
                        	else if(count==Constantes.intTRES){
                        		submodulo = cell.getStringCellValue();
                        		log.info(mensajeTrazabilidad + " submodulo " + cell.getStringCellValue());
                        	}
                        	else if(count==Constantes.intCUATRO){
                        		accesorios = cell.getStringCellValue();
                        		log.info(mensajeTrazabilidad + " accesorios " + cell.getStringCellValue());
                        	}
                        	else if(count==Constantes.intCINCO){
                        		verificar = (cell.getStringCellValue().equalsIgnoreCase(Constantes.SI)?Constantes.SUBMODULO_VERIFICAR_SI:Constantes.SUBMODULO_VERIFICAR_NO);
                        		log.info(mensajeTrazabilidad + " verificar " + cell.getStringCellValue());
                        	}
                        	else if(count==Constantes.intSEIS){
                        		componente = cell.getStringCellValue();
                        		log.info(mensajeTrazabilidad + " componente " + cell.getStringCellValue());
                        	}
                        	else if(count==Constantes.intSIETE){
                        		especificacion = cell.getStringCellValue();
                        		log.info(mensajeTrazabilidad + " especificacion " + cell.getStringCellValue());
                        	}
                        	else if(count==Constantes.intOCHO){
                        		tipo = cell.getStringCellValue();
                        		log.info(mensajeTrazabilidad + " tipo " + cell.getStringCellValue());
                        	}
                            break;
                    }
                    
                }
                
                bean.setCodigo(codigo);
                bean.setNombre_modulo(modulo);
                bean.setNombre(submodulo);
                bean.setAccesorios(accesorios);
                bean.setVerificable(verificar);
                bean.setComponente(componente);
                bean.setEspecificacion(especificacion);
                bean.setTipo(tipo);
                
                log.info(mensajeTrazabilidad + "  " + bean.toString());
                listSubModulo.add(bean);
                
            }
            
           
            log.info(mensajeTrazabilidad + " termino de leer el excel ");
            FileOutputStream out = new FileOutputStream(new File(path));
            log.info(mensajeTrazabilidad + " out ");
            workbook.write(out);
            log.info(mensajeTrazabilidad + " workbook.write(out) ");
            out.close();
            log.info(mensajeTrazabilidad + " out.close() ");
            
            
            List<TipoModuloBean> listTipoModulo = maquinariaDao.listarTipoModulo();
            
            //obtener solo modulos
            for(int i=0;i<listSubModulo.size();i++){
            	String nombreModulo = listSubModulo.get(i).getNombre_modulo();
            	log.info(mensajeTrazabilidad + "  " + listSubModulo.get(i).toString());
            	if(listModulo.size()==Constantes.intCERO){
            		log.info(mensajeTrazabilidad + " " + listSubModulo.get(Constantes.intCERO).toString());
            		String nombre_modulo = listSubModulo.get(Constantes.intCERO).getNombre_modulo().trim();
                    ModuloBean moduloBean = new ModuloBean();
                    moduloBean.setNombre(nombre_modulo);
                    moduloBean.setTipo_modulo_id_tipo_modulo(obtenerTipoModulo(listSubModulo.get(Constantes.intCERO).getTipo(),listTipoModulo));
                    listModulo.add(moduloBean);
            	}
            	log.info(mensajeTrazabilidad + " step2 ");
            	for(int j=0;j<listModulo.size();j++){log.info(mensajeTrazabilidad + " step2.1 ");
            		if(!nombreModulo.equalsIgnoreCase(listModulo.get(j).getNombre())){log.info(mensajeTrazabilidad + " step2.2 ");
            			ModuloBean modulo = new ModuloBean();
            			modulo.setNombre(nombreModulo);
            			modulo.setTipo_modulo_id_tipo_modulo(obtenerTipoModulo(listSubModulo.get(i).getTipo(),listTipoModulo));
            			listModulo.add(modulo);
            		}
            	}
            }
            //la lista final de modulos y submodulos
            log.info(mensajeTrazabilidad + " step3 ");
            for(int i=0;i<listModulo.size();i++){
            	String nombreModulo = listModulo.get(i).getNombre();
            	List<SubModuloBean> list = new ArrayList<SubModuloBean>();
            	for(int j=0;j<listSubModulo.size();j++){log.info(mensajeTrazabilidad + " step3.1 ");
            		if(nombreModulo.equals(listSubModulo.get(j).getNombre_modulo())){log.info(mensajeTrazabilidad + " step3.2 ");
            			list.add(listSubModulo.get(j));
            		}
            	}
            	
            	ModuloBean resp = listModulo.get(i);
            	resp.setListSubModulo(list);
            	log.info(mensajeTrazabilidad + " " + resp.toString());
            	listModuloEval.add(resp);
            }
            log.info(mensajeTrazabilidad + " step4 ");
            for(int i=0;i<listModuloEval.size();i++){
            	String id_modulo = maquinariaDao.guardarModulo(mensajeTrazabilidad,listModuloEval.get(i),maquinariaBean.getId_maquinaria());
            	
            	for(int j=0;j<listModuloEval.get(i).getListSubModulo().size();j++)
            	    maquinariaDao.guardarSubModulo(mensajeTrazabilidad,id_modulo,listModuloEval.get(i).getListSubModulo().get(j));
            	
            }
            
            
            
        } catch (FileNotFoundException e) {
        	log.error(mensajeTrazabilidad + " FileNotFoundException " + e.getMessage());
        } catch (IOException e) {
        	log.error(mensajeTrazabilidad + " IOException " + e.getMessage());
        } catch (InvalidFormatException e) {
        	log.error(mensajeTrazabilidad + " InvalidFormatException " + e.getMessage());
        }
        return respuesta;
  }
	
	public String obtenerTipoModulo(String tipo,List<TipoModuloBean> listTipoModulo){
		
		String id_tipo = "";
		for(int i=0;i<listTipoModulo.size();i++){
			if(tipo.equalsIgnoreCase(listTipoModulo.get(i).getTipo())){
				id_tipo = listTipoModulo.get(i).getId_tipo_modulo();
				break;
			}
		}
		
		return id_tipo;
	}
	
	
}
